关于python:更改3D绘图(Matplotlib)的垂直(z)轴的位置? 您所在的位置:网站首页 pcsx2 设置z轴 关于python:更改3D绘图(Matplotlib)的垂直(z)轴的位置?

关于python:更改3D绘图(Matplotlib)的垂直(z)轴的位置?

2023-10-31 20:38| 来源: 网络整理| 查看: 265

我正在使用 Python 中的 Matplotlib 绘制一些 3D 曲面图,并注意到一个令人讨厌的现象。根据我设置视点(相机位置)的方式,垂直 (z) 轴在左侧和右侧之间移动。这里有两个示例:示例 1,轴左,示例 2,轴右。第一个例子有 ax.view_init(25,-135) 而第二个例子有 ax.view_init(25,-45).

我希望保持相同的观点(查看数据的最佳方式)。有没有办法强制轴向一侧或另一侧?

我需要类似的东西:在两侧绘制 zaxis。感谢@crayzeewulf 的回答,我开始遵循以下解决方法(左侧、右侧或两侧):

首先根据需要绘制 3d,然后在调用 show() 之前用一个简单地覆盖 draw() 方法的 Wrapper 类package Axes3D。

Wrapper Class 调用只是简单地将一些特征的可见性设置为 False,它绘制自身并最终绘制带有修改后的 PLANES 的 zaxis。这个 Wrapper 类允许您在左侧、右侧或两侧绘制 zaxis。

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283import matplotlib matplotlib.use('QT4Agg') import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import axes3d class MyAxes3D(axes3d.Axes3D):     def __init__(self, baseObject, sides_to_draw):         self.__class__ = type(baseObject.__class__.__name__,                               (self.__class__, baseObject.__class__),                               {})         self.__dict__ = baseObject.__dict__         self.sides_to_draw = list(sides_to_draw)         self.mouse_init()     def set_some_features_visibility(self, visible):         for t in self.w_zaxis.get_ticklines() + self.w_zaxis.get_ticklabels():             t.set_visible(visible)         self.w_zaxis.line.set_visible(visible)         self.w_zaxis.pane.set_visible(visible)         self.w_zaxis.label.set_visible(visible)     def draw(self, renderer):         # set visibility of some features False         self.set_some_features_visibility(False)         # draw the axes         super(MyAxes3D, self).draw(renderer)         # set visibility of some features True.         # This could be adapted to set your features to desired visibility,         # e.g. storing the previous values and restoring the values         self.set_some_features_visibility(True)         zaxis = self.zaxis         draw_grid_old = zaxis.axes._draw_grid         # disable draw grid         zaxis.axes._draw_grid = False         tmp_planes = zaxis._PLANES         if 'l' in self.sides_to_draw :             # draw zaxis on the left side             zaxis._PLANES = (tmp_planes[2], tmp_planes[3],                              tmp_planes[0], tmp_planes[1],                              tmp_planes[4], tmp_planes[5])             zaxis.draw(renderer)         if 'r' in self.sides_to_draw :             # draw zaxis on the right side             zaxis._PLANES = (tmp_planes[3], tmp_planes[2],                              tmp_planes[1], tmp_planes[0],                              tmp_planes[4], tmp_planes[5])             zaxis.draw(renderer)         zaxis._PLANES = tmp_planes         # disable draw grid         zaxis.axes._draw_grid = draw_grid_old def example_surface(ax):    """ draw an example surface. code borrowed from http://matplotlib.org/examples/mplot3d/surface3d_demo.html"""     from matplotlib import cm     import numpy as np     X = np.arange(-5, 5, 0.25)     Y = np.arange(-5, 5, 0.25)     X, Y = np.meshgrid(X, Y)     R = np.sqrt(X**2 + Y**2)     Z = np.sin(R)     surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False) if __name__ == '__main__':     fig = plt.figure(figsize=(15, 5))     ax = fig.add_subplot(131, projection='3d')     ax.set_title('z-axis left side')     ax = fig.add_axes(MyAxes3D(ax, 'l'))     example_surface(ax) # draw an example surface     ax = fig.add_subplot(132, projection='3d')     ax.set_title('z-axis both sides')     ax = fig.add_axes(MyAxes3D(ax, 'lr'))     example_surface(ax) # draw an example surface     ax = fig.add_subplot(133, projection='3d')     ax.set_title('z-axis right side')     ax = fig.add_axes(MyAxes3D(ax, 'r'))     example_surface(ax) # draw an example surface     plt.show() 相关讨论 你能用一个实际的表面更新这个例子吗?我很难让它工作。 这是我在设置 fig 后添加绘图时得到的结果 imgur.com/VJLTTTH @pyCthon:请参阅我对示例的更新。我简单地添加了一个函数来使用从 matplotlib.org/examples/mplot3d/surface3d_demo.html 借来的代码绘制曲面。 与在 stackoverflow.com/a/49601745/1149007 中描述的 hacking ax.zaxis._axinfo['juggled'] = (0,2,1) 类似的效果

正如 OP 在下面的评论中指出的那样,下面建议的方法没有为原始问题提供足够的答案。

如本说明所述,axis3d 中有许多硬编码值,这使得自定义其行为变得困难。所以,我认为在当前的 API 中没有一个很好的方法来做到这一点。您可以通过修改 zaxis 的 _PLANES 参数来"破解"它,如下所示:

12345678tmp_planes = ax.zaxis._PLANES ax.zaxis._PLANES = ( tmp_planes[2], tmp_planes[3],                      tmp_planes[0], tmp_planes[1],                      tmp_planes[4], tmp_planes[5]) view_1 = (25, -135) view_2 = (25, -45) init_view = view_2 ax.view_init(*init_view)

现在,无论您如何旋转图形,z 轴都将始终位于图形的左侧(只要 z 轴正方向向上)。 x 轴和 y 轴将继续翻转。您可以使用 _PLANES 并且可能能够为所有轴获得所需的行为,但这在 matplotlib 的未来版本中可能会中断。

相关讨论 非常感谢 crayzeewulf。这有点奇怪,我能够让它工作,但是,它的行为不像预期的那样。当我在没有您修改的情况下运行脚本时,z 轴在左侧。当我实施您的修改时,z 轴保持在左侧。我改变了 ax.zaxis._PLANES=(tmp[0],tmp[1],tmp[2],tmp[3],tmp[4],tmp[5]) 的顺序,它把轴移到了右边侧面(我想要的)。似乎我只是重置了 ax.zaxis._PLANES 的相同值,但它获得了不同的结果。无论如何,再次感谢,这正是我想要的,我很感激。 糟糕,我错了。要更改我使用的轴 ax.zaxis._PLANES=(tmp[1],tmp[2],tmp[3],tmp[4],tmp[5],tmp[0])??。这有效;然而,我刚刚意识到它也会改变平面上的水平/垂直线。您可以在此处看到后轴平面没有水平线,但前轴平面有。是否有任何网站描述 ._PLANES 是如何定义的?我已经尝试将大约 50 种不同的组合放入其中以弄清楚,但我一直无法得到我想要的结果(右侧的垂直轴和背面的水平线) 跟进我的最后一条评论。我刚刚完成了对 tmp_planes 进行了 [0,1,2,3,4,5] 所有排列的蛮力测试,总共有 720 种不同的排列。他们都没有得到正确的数字。我想我可能只是被这个问题困住了。 威廉,我很抱歉,没有任何排列可以在不弄乱情节的其他一些特征的情况下将 z 轴保持在右侧。弄乱 _PLANES 确实是一个丑陋的混搭。确定轴位置的机制在 matplotlib 的名为 axis3d.py 的文件中实现。您可以从这段代码中看到,目前它不是很灵活,但您可以通过阅读此文件了解更多关于 _PLANES 的使用方式。您或许可以在此文件中为 Axis 类打补丁,以使其按您想要的方式工作。但这又是丑陋的。 @crayzeewulf:感谢 PLANES 的想法。在了解了它们的工作原理之后。我已经发布了一个不会弄乱其他功能并避免修补源的解决方法。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有